package domainlist

import (
	"bufio"
	"fmt"
	"os"
	"regexp"
	"strings"
)

type RItemDomain struct {
	domain string
	re     *regexp.Regexp
}

func (ri *RItemDomain) Match(domain string) bool {
	return ri.re.MatchString(domain)
}

type RListDomain struct {
	domainList []*RItemDomain // 顺序匹配
}

func NewBlankRListDomain() *RListDomain {
	return &RListDomain{
		domainList: make([]*RItemDomain, 0),
	}
}

// 将通配符转换为正则表达式
func wildcardToRegex(pattern string) (*regexp.Regexp, error) {
	regex := "^" + regexp.QuoteMeta(pattern)
	regex = regexp.MustCompile(`\\\*`).ReplaceAllString(regex, ".*")
	regex += "$"
	return regexp.Compile(regex)
}

func (L *RListDomain) Load(fileName string) error {
	file, err := os.Open(fileName)
	if err != nil {
		return err
	}
	defer file.Close()

	//var regexList []*regexp.Regexp
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		line = strings.TrimSpace(line)
		re, err := wildcardToRegex(line)
		if err != nil {
			fmt.Printf("Error compiling regex for pattern %s: %v\n", line, err)
			continue
		}
		L.Add(&RItemDomain{
			re:     re,
			domain: line,
		})
	}

	if err := scanner.Err(); err != nil {
		return err
	}

	return nil
}

// 保证调用Add时 没有进行读操作
func (L *RListDomain) Add(item *RItemDomain) error {
	L.domainList = append(L.domainList, item)
	return nil
}

func (L *RListDomain) Length() int {

	return len(L.domainList)
}

// domain 应为  url.host
// list没有加锁， 注意读写分开
func (L *RListDomain) Match(domain string) bool {
	//去除 domain 中的 :port 部分
	host := strings.Split(domain, ":")[0]
	for _, ri := range L.domainList {
		//fmt.Printf("====check [%s]  for [%s][%s]\n", ri.domain, domain, host)
		if ri.Match(host) {
			return true
		}
	}
	return false
}
